Problem Statement:

You are tasked with designing a system that adheres to the Dependency Inversion Principle (DIP) from the SOLID principles. The Dependency Inversion Principle states that high-level modules should not depend on low-level modules; both should depend on abstractions. Abstractions should not depend on details; details should depend on abstractions. The goal is to create a system where the high-level modules are not directly dependent on the low-level modules, promoting flexibility and ease of maintenance.

Solution:

  1. Define Abstractions (Interfaces):

    public interface Switchable {
        void turnOn();
        void turnOff();
    }
    public interface Device {
        void operate();
    }
  2. Create Low-Level Modules Implementing Abstractions:

    public class LightBulb implements Switchable {
        @Override
        public void turnOn() {
            System.out.println("Light bulb is on.");
        }
    
        @Override
        public void turnOff() {
            System.out.println("Light bulb is off.");
        }
    }
    public class Fan implements Switchable {
        @Override
        public void turnOn() {
            System.out.println("Fan is on.");
        }
    
        @Override
        public void turnOff() {
            System.out.println("Fan is off.");
        }
    }
    public class DeviceController implements Device {
        private Switchable device;
    
        public DeviceController(Switchable device) {
            this.device = device;
        }
    
        @Override
        public void operate() {
            device.turnOn();
            device.turnOff();
        }
    }
  3. Example Usage:

    public class Main {
        public static void main(String[] args) {
            Switchable lightBulb = new LightBulb();
            Switchable fan = new Fan();
    
            DeviceController lightBulbController = new DeviceController(lightBulb);
            DeviceController fanController = new DeviceController(fan);
    
            lightBulbController.operate();
            fanController.operate();
        }
    }